import java.io.FileWriter;
import java.io.IOException;

import com.smartxls.ChartShape;
import com.smartxls.WorkBook;

public class Test {

	public static void main(String args[]) {

		String saveFile = "test";

		// Values of test parameters.
		int GENERATIONS = 500;
		int NAGENTS = 10000;
		double DISTRIBUTION = 1.0;
		double MORTALITY = 10.0;
		double COST = 5;
		double BENEFIT = 1;
		int SHOTCOUNT = 1;
		int numberOfParameterSpaces = 20;
		int numberOfIntitialValues = 10;
		int HISTORYSIZE = 0; //0 for no history


		// Construction.
		Behavior test = null;

/*		if (HISTORYSIZE == 0) {
			test = new Behavior(NAGENTS, DISTRIBUTION, COST, BENEFIT, MORTALITY, SHOTCOUNT);
			runOnce(test, GENERATIONS, saveFile);
		} else { 
			test = new Behavior(NAGENTS, DISTRIBUTION, COST, BENEFIT, MORTALITY, SHOTCOUNT, HISTORYSIZE);
			runOnceWithMemory(test, GENERATIONS, saveFile);
		}*/
		
		
		WorkBook wb = new WorkBook();
		
		for(int row = 1; row <= numberOfIntitialValues+1; row++){
			for(int column = 1; column <= numberOfParameterSpaces+1; column++) {
				// Construction.
				test = new Behavior(NAGENTS, DISTRIBUTION+(((double)row-1)/10), COST, BENEFIT+(column-1),
						MORTALITY, SHOTCOUNT);


				System.out.println("*** Running " + test.cost + "/" + test.benefit + " and " + test.initFreqCoop + " ***");
				
				// Writing values for the axes.
				try{
					// Parameters: Row, Column, Data.
					// wb.setText(0, 0, "TEST");
					
					wb.setText(0, column, test.cost + "/" + test.benefit);
					wb.setNumber(row, 0, test.initFreqCoop);
					
				} catch (Exception e) {
					e.printStackTrace();
				}

				// Writing values for plotting.
				outputXLSSnapshot(wb, test, column, row, GENERATIONS, saveFile);
			}
		}
	}

	private static void runOnceWithMemory(Behavior behavior, int generations, String outputFileName) {
		try {
			FileWriter writer = new FileWriter("./"+outputFileName+".csv");

			for (int j = 1; j <= 10; j++) {
				// Initial data.
				writer.append(String.valueOf(behavior.getCoopRatio()));
				writer.append(',');

				// Executing test.
				for (int i = 1; i <= generations; i++) {

					// Printing the results.
					System.out.println("*** Round " + i + " ***");

					// All prisoners interact once on average.
					behavior.interactSnowDriftHistory(3, 10);

					// Agents are killed according to test the above percentage.
					behavior.mortality();

					// The same amount of killed agents are reproduced.
					behavior.reproduction();

					// Test data.
					writer.append(String.valueOf(behavior.getCoopRatio()));
					writer.append(',');
				}
				writer.append('\n');
			}
			writer.flush();
			writer.close();
		}

		catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static void outputXLSSnapshot(WorkBook wb, Behavior test, int column, int row, int generations,
			String outputFileName) {
		try {			
			// Executing test.
			for (int run = 1; run <= generations; run++) {

				// All prisoners interact once on average.
				test.interactPrisoners(3, 2);

				// Agents are killed according to the above percentage.
				test.mortality();

				// The same amount of killed agents are reproduced.
				test.reproduction();

				// Test data.
				if(run == 500) {
					wb.setNumber(row, column, test.getCoopRatio());
				}
			}
		wb.write("./" +outputFileName+"_Snapshot.xls");
		
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void outputXLSAllData(WorkBook wb, Behavior test, int column, int generations,
	String outputFileName) {
		
		try {
				// Parameters: Row, Column, Data string.
				// wb.setText(0, 0, "TEST");
				System.out.println("\n\n------ Repitition " + column + " ------");
				for(int i = 0; i <= generations; i++) {
					wb.setNumber(i, 0, i);
				}
				
				// Initial data.
				wb.setNumber(0, column, test.getCoopRatio());
				// Executing test.
				for (int row = 1; row <= generations; row++) {

					// Printing the results.
					System.out.println("*** Round " + row + " ***");

					// All prisoners interact once on average.
					test.interactSnowDrift(2, 1);

					// Agents are killed according to the above percentage.
					test.mortality();

					// The same amount of killed agents are reproduced.
					test.reproduction();

					// Test data.
					wb.setNumber(row, column, test.getCoopRatio());
				}
			wb.write("./" +outputFileName+"AllData.xls");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void outputChartXLS(Behavior behavior, int generations,
			String outputFileName) {
		WorkBook wb = new WorkBook();
		int col=1;
		
		try {
			wb.setText(0, 0, "Gen");
			
			for (int j=1;j<=10;j++) {
				// Initial data.
				// writer.append(String.valueOf(behavior.getCoopCount()));
				// writer.append(',');
				/*
				wb.setText(row, 0, j+"");							//Execution
				wb.setText(row, 1, "0");							//Generation
				wb.setText(row, 2, behavior.getCoopRatio()+"");		//Coop Ratio
				row++;*/

				//wb.setText(0, j-1, "Test #");
				wb.setText(0, col, "#"+j+" Coop");
				
				// Executing test.
				for (int i = 1; i <= generations; i++) {
					// Printing the results.
					System.out.println("*** Round " + i + " ***");
					//wb.setText(i, col-1, j+"");
					//wb.setText(i, col, i+"");
					wb.setText(i, 0, i+"");
					wb.setText(i, col, behavior.getCoopRatio()+"");
					//col++;

					// All prisoners interact once on average.
					behavior.interactSnowDrift(2, 1);

					// Agents are killed according to the above percentage.
					behavior.mortality();

					// The same amount of killed agents are reproduced.
					behavior.reproduction();
				}
				col++;
			}
			wb.insertSheets(0, 1);
			wb.setSheet(0);
			wb.setSheetName(0, "Evolutionary Game");
			ChartShape chart = wb.addChartSheet(0);

			chart.setChartType(ChartShape.Line);
			// link data source, link each series to columns(true to rows).
			chart.setLinkRange("Sheet1!$K$"+(generations+1)+"1:$A$1", false);
			// set axis title
			chart.setAxisTitle(ChartShape.XAxis, 0, "Generation");
			chart.setAxisTitle(ChartShape.YAxis, 0, "Coop Ratio");
			// set series name
			for (int j=0;j<10;j++) {
				chart.setSeriesName(j, "Simulation #"+(j+1));
			}

			wb.write("./"+outputFileName+".xls");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void runOnce(Behavior test, int generations, String saveFile) {
		// CSV-file data collection.
		try {
			FileWriter writer = new FileWriter("./"+saveFile+".csv");

			for (int j = 1; j <= 10; j++) {
				// Initial data.
				writer.append(String.valueOf(test.getCoopRatio()));
				writer.append(',');

				// Executing test.
				for (int i = 1; i <= generations; i++) {

					// Printing the results.
					System.out.println("*** Round " + i + " ***");

					// All prisoners interact once on average.
					test.interactSnowDrift(2, 1);

					// Agents are killed according to the above percentage.
					test.mortality();

					// The same amount of killed agents are reproduced.
					test.reproduction();

					// Test data.
					writer.append(String.valueOf(test.getCoopRatio()));
					writer.append(',');
				}
				writer.append('\n');
			}
			writer.flush();
			writer.close();
		}

		catch (IOException e) {
			e.printStackTrace();
		}
	}
}
